<?php

class epdo {
	protected $dbconfig;
	protected $pdo;
	protected $transactionLevel = 0;
	protected $isConnect = false;
	/**
	 * Connects to the database with the default database connection configuration
	 */
	public function connect(){
		if($this->dbconfig==NULL)return;
		if (!$this->isConnect) {
			 
			// echo "{$this->dbconfig[4]}:host={$this->dbconfig[0]};dbname={$this->dbconfig[1]}";
			 
			//'mysql:host=localhost;dbname=test',
			$this->pdo = new PDO("{$this->dbconfig[4]}:host={$this->dbconfig[0]};dbname={$this->dbconfig[1]}", $this->dbconfig[2], $this->dbconfig[3],array(PDO::ATTR_PERSISTENT => $this->dbconfig[5]));
			$this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // 当遇到错误时候发出一条错误警告
			$this->connected = true;
			if(isset($this->dbconfig['charset']) && isset($this->dbconfig['collate'])){
				$this->pdo->exec("SET NAMES '". $this->dbconfig['charset']. "' COLLATE '". $this->dbconfig['collate'] ."'");
			}
			else if(isset($this->dbconfig['charset']) ){
				$this->pdo->exec("SET NAMES '". $this->dbconfig['charset']. "'");
			}
			$this->isConnect = true;
			 
		}
	}
	
	/**
	 * Set the database configuration
	 * @param array $dbconfig Associative array of the configurations
	 * @param string $default_name Default configuration to be used
	 */
	public function setDb($dbconfig){

		$this->dbconfig = $dbconfig;
	}
	/**
	 * Close a database connection
	 */
	public function disconnect(){
		$this->pdo = null;
		$this->connected = false;
	}
	
	/**
	 * Initiates a transaction. Transactions can be nestable.
	 */
	public function beginTransaction() {
		if($this->transactionLevel === 0){
			$this->pdo->beginTransaction();
		}
		else{
			$this->pdo->exec("SAVEPOINT LEVEL{$this->transactionLevel}");
		}
		$this->transactionLevel++;
	}
	
	/**
	 * Commits a transaction. Transactions can be nestable.
	 */
	public function commit() {
		$this->transactionLevel--;
		if($this->transactionLevel === 0){
			$this->pdo->commit();
		}
		else{
			$this->pdo->exec("RELEASE SAVEPOINT LEVEL{$this->transactionLevel}");
		}
	}
	
	/**
	 * Rolls back a transaction. Transactions can be nestable.
	 */
	public function rollBack() {
		$this->transactionLevel--;
		if($this->transactionLevel === 0){
			$this->pdo->rollBack();
		}
		else{
			$this->pdo->exec("ROLLBACK TO SAVEPOINT LEVEL{$this->transactionLevel}");
		}
	}
	
	/**
	 * Execute a query to the connected database
	 * @param string $query SQL query prepared statement
	 * @param array $param Values used in the prepared SQL
	 * @return PDOStatement
	 */
	public function query($query, $param=null){
		 
		$stmt = $this->pdo->prepare($query);
		$stmt->setFetchMode(PDO::FETCH_ASSOC); //以数据库字段返回数据集
	
		if($param==null)
			$stmt->execute();
		else
			$stmt->execute($param);
		return $stmt;
	}
	
	/*
	 * Execute a query and Fetch single row
	* @param string $query SQL query prepared statement
	* @param array $param Values used in the prepared SQL
	* @param int $fetchMode  PDO Fetch mode for the statement
	* @param mixed $fetchModeOptionalParam1 First Optional Param for PDOStatement::setFetchMode
	* @param mixed $fetchModeOptionalParam2 Second Optional Param for PDOStatement::setFetchMode
	* @return Returns an array a row from the result set
	*/
	public function fetchRow($query, $param = null, $fetchMode = null, $fetchModeOptionalParam1=null, $fetchModeOptionalParam2=array()) {
		$stmt = $this->query($query, $param);
		if($fetchMode!==null) {
			switch($fetchMode) {
				case PDO::FETCH_COLUMN:
					$stmt->setFetchMode($fetchMode, ($fetchModeOptionalParam1 !== null) ? $fetchModeOptionalParam1 : 0);
					break;
				case PDO::FETCH_CLASS:
					$stmt->setFetchMode($fetchMode, $fetchModeOptionalParam1, $fetchModeOptionalParam2);
					break;
				case PDO::FETCH_INTO:
					$stmt->setFetchMode($fetchMode, $fetchModeOptionalParam1);
					break;
				default:
					$stmt->setFetchMode($fetchMode);
			}
		}
		return $stmt->fetch();
	}
	
	/*
	 * Execute a query and Fetch multiple rows
	* @param string $query SQL query prepared statement
	* @param array $param Values used in the prepared SQL
	* @param int $fetchMode  PDO Fetch mode for the statement
	* @param mixed $fetchModeOptionalParam1 First Optional Param for PDOStatement::setFetchMode
	* @param mixed $fetchModeOptionalParam2 Second Optional Param for PDOStatement::setFetchMode
	* @return Returns an array containing all of the result set rows
	*/
	public function fetchAll($query, $param = null, $fetchMode = null, $fetchModeOptionalParam1=null, $fetchModeOptionalParam2=array()) {
		$stmt = $this->query($query, $param);
		if($fetchMode!==null) {
			switch($fetchMode) {
				case PDO::FETCH_COLUMN:
					$stmt->setFetchMode($fetchMode, ($fetchModeOptionalParam1 !== null) ? $fetchModeOptionalParam1 : 0);
					break;
				case PDO::FETCH_CLASS:
					$stmt->setFetchMode($fetchMode, $fetchModeOptionalParam1, $fetchModeOptionalParam2);
					break;
				case PDO::FETCH_INTO:
					$stmt->setFetchMode($fetchMode, $fetchModeOptionalParam1);
					break;
				default:
					$stmt->setFetchMode($fetchMode);
			}
		}
		return $stmt->fetchAll();
	}
	
	
	
	 
	/**
	 * Quotes a string for use in a query.
	 *
	 * Places quotes around the input string and escapes and single quotes within the input string, using a quoting style appropriate to the underlying driver.
	 * @param string $string The string to be quoted.
	 * @param int $type Provides a data type hint for drivers that have alternate quoting styles. The default value is PDO::PARAM_STR.
	 * @return string Returns a quoted string that is theoretically safe to pass into an SQL statement. Returns FALSE if the driver does not support quoting in this way.
	 */
	public function quote($string, $type=null) {
		return $this->pdo->quote($string, $type);
	}
	/**
	 * 格式话数据库参数
	 * @param unknown_type $array
	 * @param unknown_type $type
	 * @return string
	 */
	public function quoteArray($array, $type=null) {
		if (!is_array($array)) {
			return $this->quote($array, $type);
		}
		$numItems = count($array);
		for($i=0; $i<$numItems; $i++) {
			if (is_array($array[$i])) {
				$array[$i] = $this->quoteArray($array[$i], $type);
			} else {
				$array[$i] = $this->quote($array[$i]);
			}
		}
		return $array;
	}
	
	/**
	 * Returns the last inserted record's id
	 * @return int
	 */
	public function lastInsertId() {
		return $this->pdo->lastInsertId();
	}
	
	/**
	 * Returns the underlying PDO object used in DooSqlMagic
	 * @return PDO
	 */
	public function getDbObject(){
		return $this->pdo;
	}
}

?>